#pragma once
#include <typeinfo>
#include <utility>

class Any
{

public:
    class holder
    {
    public:
        virtual ~holder(){};
        virtual const std::type_info &type() = 0; // 用于类型判断
        virtual holder *clone() = 0;              // 用与深拷贝
    };
    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T &val = T()) : _val(val){}; //
        virtual const std::type_info &type()           // 实现 type() 是为了 typeid 类型判断
        {
            return typeid(T);
        };
        virtual holder *clone() // 为了实现拷贝构造：Any a = b 时，必须复制内部内容
        {
            return new placeholder(_val);
        };
        T _val;
    };

    Any();
    template <class T>
    Any(const T &content);
    Any(const Any &other);
    ~Any();

    // 成员函数
    Any &swap(Any &other);
    template <class T>
    Any &operator=(const T &val);
    Any &operator=(const Any &other);

    template <class T>
    T *get()
    {
        if (!_content || typeid(T) != _content->type())
            return nullptr;
        return &(static_cast<placeholder<T> *>(_content)->_val);
    }

public:
    holder *_content;
};

// 模板构造函数必须在头文件中定义
template <class T>
Any::Any(const T &content) : _content(new placeholder<T>(content)) {}

template <class T>
Any &Any::operator=(const T &val)
{
    Any(val).swap(*this);
    return *this;
}